class DEAPool
  DEA_PROFILE_EXPIRATION_TIME = 10
  @dea_res_info = {}
  class << self
    def dea_profiles
      @dea_profiles ||= {}
    end

    def process_advertise_message(msg)
      CloudController.logger.debug("Got DEA advertisement#{msg}.")
      dea_profiles[msg[:id]] = {:profile => msg, :time => Time.now.to_i}
      dea_uuid = msg[:id]
      if msg[:id] == dea_uuid
        @dea_res_info[dea_uuid] = msg
      else
        @dea_res_info
      end
      available_memory = calculate_available_memory
      #CloudController.logger.info("--ava_mem: #{available_memory}")
      CloudController.logger.info("--@dea_res_info: #{@dea_res_info}--")
    end

    def find_dea(app)
      required_mem = app[:limits][:mem]
      required_runtime = app[:runtime_info]
      prod = app[:prod]
      keys = dea_profiles.keys.shuffle                             #随机排列数组
      keys.each do |key|
        entry = dea_profiles[key]
        dea = entry[:profile]
        last_update = entry[:time]
        if Time.now.to_i - last_update > DEA_PROFILE_EXPIRATION_TIME
          CloudController.logger.debug("DEA #{dea[:id]} expired from pool.")
          dea_profiles.delete(key)
          next
        end

        if  (dea[:available_memory] >= required_mem) &&
            (dea[:runtimes].member? required_runtime['name']) &&
            # non-prod DEAs can host either prod or non-prod apps
            # prod DEAs can host prod apps
            (!dea[:prod] || prod)
          CloudController.logger.debug("Found DEA #{dea[:id]}.")
          return dea[:id]
        end
      end
      nil
    end

    #return dea status to resource_pool_controller
    def dea_status_summary
      return [] if @dea_res_info.nil?
      @dea_res_info.each do |key,instance|
        time = Time.now.to_i
        if time - instance[:time] > 30
          uuid = key
          @dea_res_info.delete(uuid)
        elsif time - instance[:time] > 10
          instance[:state] = "DOWN"
          instance[:max_memory] = 0
          instance[:reserved_memory] = 0
          instance[:max_disk] = 0
          instance[:reserved_disk] = 0
        else
          @dea_res_info
        end
      end
      @dea_res_info
    end

    #caclculate dea number
    def calculate_dea_num
      @dea_res_info.size
    end

    #calculate max memory of all deas
    def calculate_max_memory
      max_memory = []
      @dea_res_info.each_value do |instance|
        max_memory << instance[:max_memory] if instance[:max_memory]
      end
      eval max_memory.join('+')
    end

    #calculate reserved memory of all deas
    def calculate_reserved_memory
      reserved_memory = []
      @dea_res_info.each_value do |instance|
        reserved_memory << instance[:reserved_memory] if instance[:reserved_memory]
      end
      eval reserved_memory.join('+')
    end

    #calculate availabe memory of all deas
    def calculate_available_memory
      available_memory = []
      @dea_res_info.each_value do |instance|
        available_memory << instance[:available_memory] if instance[:available_memory]
      end
      eval available_memory.join('+')
    end

    #calculate max disk of all deas
    def calculate_max_disk
      max_disk = []
      @dea_res_info.each_value do |instance|
        max_disk << instance[:max_disk] if instance[:max_disk]
      end
      eval max_disk.join('+')
    end

    #calculate reserved disk of all deas
    def calculate_reserved_disk
      reserved_disk = []
      @dea_res_info.each_value do |instance|
        reserved_disk << instance[:reserved_disk] if instance[:reserved_disk]
      end
      eval reserved_disk.join('+')
    end

    #calculate available disk of all deas
    def calculate_available_disk
      available_disk = []
      @dea_res_info.each_value do |instance|
        available_disk << instance[:available_disk] if instance[:available_disk]
      end
      eval available_disk.join('+')
    end

  end
end
